/* 
 * Copyright (c) 2011-, Agilord Kft. - All Rights Reserved.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at 
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.agilord.dragonflyp4.module;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import com.agilord.dragonflyp4.Configuration;
import com.agilord.dragonflyp4.ExifUtils;
import com.agilord.dragonflyp4.ImageFile;
import com.agilord.dragonflyp4.ProcessModule;

/**
 * Some little hack for preparing the photo for smugmug publishing. Extends the
 * description with headline and location, includes the rating in the keywords
 * (and within the 30 keyword limit)
 * 
 * @author Istvan Soos
 * @since 1.0
 */
public class SmugmugModule implements ProcessModule {

	protected int keywords;
	protected Integer ratingMin = null;
	protected Integer ratingMax = null;
	protected String ratingPrefix = null;

	public SmugmugModule() {
		super();
		try {
			this.keywords = Integer.parseInt(Configuration.get().getProps()
			        .getProperty("smugmug.keywords", "30"));
		} catch (Exception ex) {
			throw new RuntimeException(ex);
		}

		try {
			String rcfg = Configuration.get().getProps().getProperty("smugmug.rating.range");
			if (rcfg != null) {
				String[] parts = rcfg.split("\\-", 2);
				if (parts.length == 1) {
					ratingMin = Integer.parseInt(parts[0]);
					ratingMax = ratingMin;
				} else {
					ratingMin = Integer.parseInt(parts[0]);
					ratingMax = Integer.parseInt(parts[1]);
				}
				ratingMin = Math.max(ratingMin, 1);
				ratingMax = Math.max(ratingMin, ratingMax);
			}
			this.ratingPrefix = Configuration.get().getProps().getProperty("smugmug.rating.prefix", "r");
		} catch (Exception ex) {
			throw new RuntimeException(ex);
		}
	}

	public void process(ImageFile image) {
		extendDescription(image);
		extendKeywordsWithRating(image);
	}

	protected void extendKeywordsWithRating(ImageFile image) {
		if (ratingMin == null)
			return;
		Long rv = ExifUtils.getLongValue(image.getExif(), "Rating");
		if (rv == null)
			return;
		// oh, I'll explain this someday
		int r = rv.intValue();

		if (r >= ratingMin) {
			List<String> orig = ExifUtils.getStringList(image.getExif(), "Keywords");
			orig = orig == null ? new LinkedList<String>() : new LinkedList<String>(orig);

			// rating keywords
			List<String> rks = new ArrayList<String>();
			for (int rk = ratingMin; rk <= ratingMax && rk <= r; rk++)
				rks.add(ratingPrefix + rk);

			// new list
			Set<String> keys = new LinkedHashSet<String>();
			int limit = keywords - rks.size();
			while (!orig.isEmpty() && limit > keys.size()) {
				keys.add(orig.remove(0));
			}
			keys.addAll(rks);
			keys.addAll(orig);

			ExifUtils.setKeywords(image, keys);
		}
	}

	protected void extendDescription(ImageFile image) {
		String headline = ExifUtils.getTitle(image.getExif());
		String description = ExifUtils.getDescription(image.getExif());
		String location = ExifUtils.getLocation(image.getExif());

		if (headline != null) {
			if (description == null) {
				description = headline.trim();
			} else {
				if (!description.startsWith(headline))
					description = (headline.trim() + "\n\n" + description).trim();
			}
		}

		if (location != null) {
			if (description == null) {
				description = location;
			} else {
				if (!description.contains(location))
					description = (description.trim() + "\n\n" + location.trim()).trim();
			}
		}

		if (description != null && !description.equals(ExifUtils.getDescription(image.getExif()))) {
			ExifUtils.setDescription(image, description);
		} else if (description == null) {
			System.out.println("  ! - no description!?");
		}
	}

	public void reportSummary() {
	}

}
